package com.boss.common.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.boss.api.dto.ApiResultDTO;
import com.boss.asset.service.IAssetInfoService;
import com.boss.common.entity.User;
import com.boss.common.entity.WfActionDTO;
import com.boss.common.service.ICommonService;
import com.boss.common.util.DateUtils;
import com.boss.config.FileServiceConfiguration;
import com.boss.framework.exception.AppRuntimeException;
import com.boss.salary.constant.ApiElementConstant;
import com.boss.salary.constant.SystemDictConstant;
import com.boss.salary.dao.*;
import com.boss.salary.entity.AgencyInfo;
import com.boss.salary.entity.ConfigCtrl;
import com.boss.salary.entity.PersonOperate;
import com.boss.salary.entity.SalaryBasedata;
import com.boss.salary.service.IAgencyInfoService;
import com.boss.salary.service.INotInPaymentService;
import com.boss.sys.ca.user.dto.UserDTO;
import com.boss.sys.config.CseCommonConfiguration;
import com.boss.sys.utils.SysUtils;
import io.seata.spring.annotation.GlobalTransactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class CommonServiceImpl  implements ICommonService{

    private final static Logger logger = LoggerFactory.getLogger(CommonServiceImpl.class);

    private  static String SSO="/v2/user/token";
    private  static String CHANGYEEAR="/v2/changeyear";
    private  static String PERM="/v2/menus";
    private  static String USERLOGIN="/v2/userlogin";
    private  static String UPLOADFILE="/v2/upload";
    private  static String MENUTREE="/v1/menutreeinfo";
    private  static String APPGUID="salary";
    private  static String CHECKTOKEN="/v2/checktoken/";
    private  static String LOGOUT = "/v2/loginout/";
    private static String PAYMENTCOUNT = "/v1/ctrl/count";
    private static String PAYMENTPAGE = "/v1/ctrl/pageInfo";
    /** 生成支付申请*/
    private static String SENTPAYMENT = "/v2/payvoucher/action/insert/salary";
    /** 生成支付申请异步*/
    private static String SENTPAYMENTASYNC = "/v2/payvoucher/action/big/insert/salary";
    /**生成支付申请异步获取进度 */
    private static String SENTPAYMENTPROGRESS = "/v2/payvoucher/query/bigsalary/progress/bar";
    private static String NULLIFYPAYMENT = "/v2/payvoucher/action/discard/salary";
    private static String AGENCYINFO = "/v1/agency/getAgencyInfo";
    /** 根据bizKey查询流程信息接口地址 **/
    private static String WORKFLOW_INTODO = "/v2/workflow/menus/intodo?processDefKey=%s&bizKey=%s&province=%s&year=%s";
    /** 平台消息推送接口地址*/
    private static String SYSNOTICES="/v2/sysnotices/agencyright-user";
    /**指标冻结（采购）*/
    private static String GOCPURBUDGETFROZEN="/v1/budget/budgetfrozen/gocpurbudgetFrozen";
    /**指标解冻（采购）*/
    private static String GOCPURBUDGETTHAW="/v1/budget/budgetfrozen/gocpurbudgetThaw";
    /**指标冻结（采购）*/
    private static String BATCHGOCPURBUDGETFROZEN="/v1/budget/budgetfrozen/batch/gocpurbudgetFrozen";
    /**指标解冻（采购）*/
    private static String BATCHGOCPURBUDGETTHAW="/v1/budget/budgetfrozen/batch/gocpurbudgetThaw";
    /** 获取工作流查询语句  sql中调用 **/
    private static  String  WORKFLOW_WHERESQL= "/v2/workflow/task/wheresql";
    /**获取系统参数*/
    private static String PARAMS_CONFIG="/v2/params";

    /**
     * 引入接口服务配置类
     */
    @Autowired
    private CseCommonConfiguration urlConfiguration;

    @Autowired
    private FileServiceConfiguration fileServiceConfiguration;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private IBaseDateDao iBaseDateDao;

    @Autowired
    private IAgencyInfoService iAgencyInfoService;

    @Autowired
    private IAssetInfoService iAssetInfoService;
    @Autowired
    private IPayMentLockDao iPayMentLockDao;
    @Autowired
    private IConfigCtrlDao iConfigCtrlDao;
    @Autowired
    private INotInPaymentService notInPayMentService;
    @Autowired
    private ISalaryBasedataDao salaryBasedataDao;
    @Autowired
    private IAgencyInfoDao agencyInfoDao;


    @Override
    public User getUserByToken(User user)  throws AppRuntimeException {
        try{
            String json = restTemplate.getForObject(urlConfiguration.getSso()+SSO+"/{tokenid}",String.class,user.getToken());
            Map<String,String> resultMap = new HashMap<>();
            JSONObject jsonObject = JSON.parseObject(json);
            if(!SysUtils.isNullOrEmpty(jsonObject) && "100000".equals(jsonObject.getString("rscode"))){
                JSONObject jsondata = jsonObject.getJSONObject("data");
                user.setUserguid(jsondata.getString("guid"));
                user.setName(jsondata.getString("name"));
                user.setAgencyId(jsondata.getString("agency"));
                user.setAgencyCode(jsondata.getString("orgcode"));
                user.setAgencyname(jsondata.getString("orgname"));
                user.setProvince(jsondata.getString("province"));
                user.setYear(jsondata.getInteger("year"));
                user.setAdmdiv(jsondata.getString("admdivname"));
            }
            return user;
        } catch (Exception e) {
//            throw new AppRuntimeException("查询用户信息失败！");

            user.setProvince("619900000");
            user.setYear(2020);
            return user;
        }
    }

    @Override
    public void changeYear(String tokenid,String year) throws AppRuntimeException {
        StringBuilder url = new StringBuilder();
        url.append(urlConfiguration.getUserservice()+CHANGYEEAR);
        url.append("/");
        url.append(tokenid);
        url.append("/pay/");
        url.append(year);
        String json = restTemplate.getForObject(url.toString(),String.class);
    }

    @Override
    public Map<String, String> getMenusByUserGuid(String year, String province, String userguid) {
        StringBuilder url = new StringBuilder();
        url.append(urlConfiguration.getPermservice()+PERM+"?appids=[\"salary\"]");
        url.append("&year=");
        url.append(year);
        url.append("&province=");
        url.append(province);
        if(null!=userguid){
            url.append("&userguid=");
            url.append(userguid);
        }
        String json = restTemplate.getForObject(url.toString(),String.class);
        Map<String,String> resultMap = new HashMap<>();
        JSONObject jsonObject = JSON.parseObject(json);
        if(!SysUtils.isNullOrEmpty(jsonObject) && "100000".equals(jsonObject.getString("rscode"))){
            JSONArray jsonArray = jsonObject.getJSONArray("data");

        }
        resultMap.put("json",json);
        return resultMap;
    }

    /**
     * 现在不好使报错不要调用
     * @param user
     * @return
     */
    @Override
    public Map<String, String> getUserLogin(User user) {
        JSONObject params=new JSONObject();
        params.put("username",user.getUsername());
        params.put("password",user.getPassword());
        String json = restTemplate.postForObject(urlConfiguration.getSso()+USERLOGIN,params.toJSONString(),String.class);
        Map<String,String> resultMap = new HashMap<>();
        resultMap.put("json",json);
        return resultMap;
    }

    /**
     * 返回map中get("fileid")获取，该方法只有外网走网关可以使用,billguid通过上传后返回值插入数据库
     * @param file
     * @return
     */

    @Override
    public Map<String, String> uploadFile( MultipartFile file) throws  Exception{
        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
        String billguid=SysUtils.generateGuid();
        params.add("appid",APPGUID);
        params.add("billguid",billguid);
        params.add("file",file);
        String json = restTemplate.postForObject(urlConfiguration.getFileservice()+UPLOADFILE,params,String.class);
        Map<String,String> resultMap = new HashMap<>();
        JSONObject jsonObject = JSON.parseObject(json);
        if(!SysUtils.isNullOrEmpty(jsonObject) && "100000".equals(jsonObject.getString("rscode"))){
            resultMap.put("fileid",jsonObject.getString("data"));
            resultMap.put("billguid",billguid);
        }else {
            throw new Exception("upload file failure!");
        }
        return resultMap;
    }


    /**
     * 通过token获取系统菜单
     * @param user
     * @return
     */
    @Override
    public Map<String, String> getMenuTree(User user) {


        String url=urlConfiguration.getPermservice()+MENUTREE;
        Map<String,String> resultMap = new HashMap<>();

        HttpHeaders headers = new HttpHeaders();
        headers.add("tokenid",user.getToken());
        headers.add("appguid",APPGUID);
        HttpEntity<String> requestEntity = new HttpEntity<>(null, headers);
        //String urlTemplate = "http://localhost/test?id=%s&type_id=%s";
        //String url = String.format(urlTemplate,1,2);
        ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
        resultMap.put("menus",responseEntity.getBody().toString());
        return resultMap;
    }

    /**
     * paramMap(mof_div_code,fiscal_year,limit,offset,condition)condition里可以拼sql 例如 and agency_id="****"
     * @param paramMap
     * @return
     */
    @Override
    public JSONArray getPayMent(Map<String,Object> paramMap, boolean initIndex) {
        logger.info("==== call getPayMent interface into params ：" + paramMap);
        String mof_div_code=paramMap.get("mof_div_code")==null?"220000000":paramMap.get("mof_div_code").toString();
        String fiscal_year=paramMap.get("fiscal_year")==null?"2022":paramMap.get("fiscal_year").toString();
        String limit=paramMap.get("limit")==null?"100":paramMap.get("limit").toString();
        String offset=paramMap.get("offset")==null?"0": String.valueOf((Integer.parseInt(paramMap.get("offset").toString())-1)*Integer.parseInt(paramMap.get("limit").toString()));
        ConfigCtrl cc= iConfigCtrlDao.selectConfigCtrlByTypeMof("bgttypeAble",mof_div_code);
        String url= fileServiceConfiguration.getGlService() + PAYMENTPAGE +"?" +
                "acct_cls_id=4E72561AB3CD477EB8DFD51813EC2FB2" +
                "&mof_div_code=" +mof_div_code+
                "&fiscal_year=" +fiscal_year+
                "&is_have_zero=1" +
                "&limit=" +limit+
                "&offset="+offset;
        Map<String,String> requestMap = new HashMap<>();
        StringBuffer condition=new StringBuffer();
//        condition.append(" and is_sal='1' ");
        if(StringUtils.isEmpty(cc)||"1".equals(cc.getIsAble())) {
            condition.append(" and bgt_type_code='21' ");
        }
        condition.append(" and pay_type_code='1' ");//统发只取国库集中支付
        if (paramMap.containsKey("condition")) {
            String incondition=paramMap.get("condition").toString();
            if (!StringUtils.isEmpty(incondition)) {
                if(incondition.trim().startsWith("and")){
                    condition.append(incondition);
                } else {
                    condition.append(" and ");
                    condition.append(incondition);
                }
            }
        }
        //添加不查询的过滤条件
        String notin=notInPayMentService.getNotInPaymentCondition(mof_div_code);
        if(!StringUtils.isEmpty(notin)){
            condition.append(notin);
        }
        condition.append(" order by sum_id ");
        requestMap.put("condition",condition.toString());
        logger.info("==== call getPayMent interface url ：" + url);
        logger.info("==== call getPayMent interface requestMap ：" + requestMap);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<Map<String,String>> requestEntity = new HttpEntity<Map<String,String>>(requestMap, headers);
        String json= restTemplate.postForObject(url,requestEntity, String.class);
        JSONObject jsonObject = JSONObject.parseObject(json);
        String rscode = jsonObject.getString("rscode");
        logger.info("==== call getPayMent interface return ：" + jsonObject);
        if (!"200".equals(rscode)) {
            throw new AppRuntimeException(jsonObject.get("result").toString());
        }
        JSONArray jsonArray = jsonObject.getJSONArray("data");
        JSONArray requestJsonArray=new JSONArray();
        if (!StringUtils.isEmpty(jsonArray) && jsonArray.size() > 0) {
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject obj = jsonArray.getJSONObject(i);
                JSONObject reobj=new JSONObject();
                /*BigDecimal Dr_inc_acc_amt = obj.getBigDecimal("dr_inc_acc_amt");
                BigDecimal Dr_dec_acc_amt = obj.getBigDecimal("dr_dec_acc_amt");
                BigDecimal aviamt = Dr_inc_acc_amt.subtract(Dr_dec_acc_amt);*/
                BigDecimal aviamt = obj.getBigDecimal("avi_amt");
                // 总额度
                reobj.put("aviamt", aviamt);
                /*BigDecimal Cr_inc_acc_amt = obj.getBigDecimal("cr_inc_acc_amt");
                BigDecimal Wip_cr_inc_amt = obj.getBigDecimal("wip_cr_inc_amt");
                BigDecimal Cr_dec_acc_amt = obj.getBigDecimal("cr_dec_acc_amt");
                BigDecimal canuseamt = aviamt.subtract(Cr_inc_acc_amt.add(Wip_cr_inc_amt).subtract(Cr_dec_acc_amt));*/
                //计划占用额度
                BigDecimal balance_useamt = obj.getBigDecimal("balance_useamt");
                balance_useamt=balance_useamt==null?new BigDecimal("0.00"):balance_useamt;
                //当前冻结指标
                BigDecimal frozen_amt=obj.getBigDecimal("frozen_amt");
                frozen_amt=frozen_amt==null?new BigDecimal("0.00"):frozen_amt;
                //总额度减计划占用减指标冻结后
                BigDecimal balance_canuseamt= aviamt.subtract(balance_useamt).subtract(frozen_amt);
                //可用额度
                BigDecimal canuseamt = obj.getBigDecimal("canuse_amt");
                if(canuseamt.compareTo(balance_canuseamt) == 1){//可用额度>总额度减计划占用后额度
                    // 剩余可用额度
                    reobj.put("canuseamt", balance_canuseamt);
                }else{
                    // 剩余可用额度
                    reobj.put("canuseamt", canuseamt);
                }
                reobj.put("sum_id", obj.getString("sum_id"));
                reobj.put("gov_bgt_eco", obj.getString("gov_bgt_eco"));
                reobj.put("depBgtEcoNo", obj.getString("depBgtEcoNo"));
                reobj.put("agency_code", obj.getString("agency_code"));
                reobj.put("gov_bgt_eco_name", obj.getString("gov_bgt_eco_name"));
                reobj.put("pay_category_name", obj.getString("pay_category_name"));
                reobj.put("depBgtEcoName", obj.getString("depBgtEcoName"));
                reobj.put("agency_id", obj.getString("agency_id"));
                reobj.put("bgtId", obj.getString("sum_id"));
                reobj.put("payTypeName", obj.getString("pay_type_name"));
                reobj.put("expFuncCode", obj.getString("exp_func_code"));
                reobj.put("expFuncName", obj.getString("exp_func_name"));
                reobj.put("corBgtDocNoName", obj.getString("cor_bgt_doc_no_name"));
                reobj.put("fundTypeName", obj.getString("fund_type_name"));
                reobj.put("proCatName", obj.getString("pro_cat_name"));
                reobj.put("proName", obj.getString("pro_name"));
                reobj.put("agencyId", obj.getString("agency_id"));
                reobj.put("agencyName", obj.getString("agency_name"));
                reobj.put("depBgtEcoNo", obj.getString("dep_bgt_eco_code"));
                reobj.put("depBgtEcoName", obj.getString("dep_bgt_eco_name"));
                if (initIndex) {
                    reobj.put("isUsing", "1");
                    reobj.put("payOrder", "1");
                }
                requestJsonArray.add(reobj);
            }
        }
        return requestJsonArray;
    }

    @Override
    public int getPayMentCount(Map<String, Object> paramMap, boolean initIndex) {
        String mof_div_code=paramMap.get("mof_div_code")==null?"220000000":paramMap.get("mof_div_code").toString();
        String fiscal_year=paramMap.get("fiscal_year")==null?"2022":paramMap.get("fiscal_year").toString();
        ConfigCtrl cc= iConfigCtrlDao.selectConfigCtrlByTypeMof("bgttypeAble",mof_div_code);
        String url= fileServiceConfiguration.getGlService() +PAYMENTCOUNT+"?" +
                "acct_cls_id=4E72561AB3CD477EB8DFD51813EC2FB2" +
                "&mof_div_code=" +mof_div_code+
                "&fiscal_year=" +fiscal_year+
                "&is_have_zero=1";
        Map<String,String> requestMap = new HashMap<>();
        StringBuffer condition=new StringBuffer();
        if(StringUtils.isEmpty(cc)||"1".equals(cc.getIsAble())) {
            condition.append(" and bgt_type_code='21' ");
        }
        String incondition=paramMap.get("condition").toString();
        if (!StringUtils.isEmpty(incondition)) {
            if(incondition.trim().startsWith("and")){
                condition.append(incondition);
            } else {
                condition.append(" and ");
                condition.append(incondition);
            }
        }
        //添加不查询的过滤条件
        String notin=notInPayMentService.getNotInPaymentCondition(mof_div_code);
        if(!StringUtils.isEmpty(notin)){
            condition.append(notin);
        }
        requestMap.put("condition",condition.toString());
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<Map<String,String>> requestEntity = new HttpEntity<Map<String,String>>(requestMap, headers);
        String json= restTemplate.postForObject(url,requestEntity, String.class);
        JSONObject jsonObject = JSONObject.parseObject(json);
        String rscode = jsonObject.getString("rscode");
        if (!"200".equals(rscode)) {
            throw new AppRuntimeException(jsonObject.get("result").toString());
        }
        int total = jsonObject.getInteger("data");
        return total;
    }


    /**
     * 通过指标id查询可用额度
     * @param bgtids,userDTO
     * @return
     */
    @Override
    public Map<String,BigDecimal> getPayMent(List<String> bgtids,UserDTO userDTO) {

        Map<String,BigDecimal> bgt=new HashMap<>();
        logger.info("==== call payment interface into params ：" + bgtids);
        String mof_div_code=userDTO.getProvince()==null?"220000000":userDTO.getProvince();
        String fiscal_year=userDTO.getYear()==null?"2022":userDTO.getYear().toString();
        String limit="100000";
        String offset="0";
        String url= fileServiceConfiguration.getGlService() + PAYMENTPAGE +"?" +
                "acct_cls_id=4E72561AB3CD477EB8DFD51813EC2FB2" +
                "&mof_div_code=" +mof_div_code+
                "&fiscal_year=" +fiscal_year+
                "&is_have_zero=0" +
                "&limit=" +limit+
                "&offset="+offset;
        Map<String,String> requestMap = new HashMap<>();

        StringBuilder sql = new StringBuilder();
        sql.append(" and ");
        sql.append(SysUtils.inSql("sum_id", bgtids));
        requestMap.put("condition",sql.toString());
        logger.info("==== call payment interface url ：" + url);
        logger.info("==== call payment interface requestMap ：" + requestMap);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<Map<String,String>> requestEntity = new HttpEntity<Map<String,String>>(requestMap, headers);
        String json= restTemplate.postForObject(url,requestEntity, String.class);
        JSONObject jsonObject = JSONObject.parseObject(json);
        String rscode = jsonObject.getString("rscode");
        logger.info("==== call payment interface return ：" + jsonObject);
        if (!"200".equals(rscode)) {
            throw new AppRuntimeException(jsonObject.get("result").toString());
        }
        JSONArray jsonArray = jsonObject.getJSONArray("data");
        if (!StringUtils.isEmpty(jsonArray) && jsonArray.size() > 0) {

            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject obj = jsonArray.getJSONObject(i);
                BigDecimal aviamt = obj.getBigDecimal("avi_amt");
                // 总额度
                obj.put("aviamt", aviamt);
                //计划占用额度
                BigDecimal balance_useamt = obj.getBigDecimal("balance_useamt");
                balance_useamt=balance_useamt==null?new BigDecimal("0.00"):balance_useamt;
                //当前冻结指标
                BigDecimal frozen_amt=obj.getBigDecimal("frozen_amt");
                frozen_amt=frozen_amt==null?new BigDecimal(0):frozen_amt;
                //总额度减计划占用减指标冻结后
                BigDecimal balance_canuseamt= aviamt.subtract(balance_useamt).subtract(frozen_amt);
                //可用额度
                BigDecimal canuseamt = obj.getBigDecimal("canuse_amt");
                if(canuseamt.compareTo(balance_canuseamt) == 1){//可用额度>总额度减计划占用后额度
                    // 剩余可用额度
                    bgt.put(obj.getString("sum_id"),balance_canuseamt);
                }else{
                    // 剩余可用额度
                    bgt.put(obj.getString("sum_id"),canuseamt);
                }

            }
        }
        return bgt;
    }
    /**
     * paramMap请求内容请参考接口文档
     * @param paramMap
     * @return
     */
    @Override
    public Map<String, String> sentPayMent(List<Map<String, Object>> paramMap,String tokenid) {
        logger.info("==== call sendpayment interface into params ：" + paramMap);
        String url = fileServiceConfiguration.getPayVoucherService() + SENTPAYMENT;
        Map<String,String> resultMap = new HashMap<>(1);
        HttpHeaders headers = new HttpHeaders();
        headers.add("tokenid",tokenid);
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<List<Map<String, Object>>> requestEntity = new HttpEntity<>(paramMap, headers);
        ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
        resultMap.put("result",responseEntity.getBody());
        logger.info("==== call sendpayment interface out result ：" + resultMap);
        return resultMap;
    }

    /**
     * 推送支付异步接口
     * @param paramMap
     * @param tokenid
     * @return
     */
    @Override
    public Map<String, String> sentPaymentAsync(List<Map<String, Object>> paramMap, String tokenid) {
        logger.info("==== call sendPaymentAsync interface into params ：" + paramMap);
        String url = fileServiceConfiguration.getPayVoucherService() + SENTPAYMENTASYNC;
        Map<String,String> resultMap = new HashMap<>(1);
        HttpHeaders headers = new HttpHeaders();
        headers.add("tokenid",tokenid);
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<List<Map<String, Object>>> requestEntity = new HttpEntity<>(paramMap, headers);
        ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
        resultMap.put("result",responseEntity.getBody());
        logger.info("==== call sendPaymentAsync interface out result ：" + resultMap);
        return resultMap;
    }

    @Override
    public Map<String, Object> sentPaymentProgress(String id) {
        logger.info("==== call sentPaymentProgress interface into params ：" + id);
        String url = fileServiceConfiguration.getPayVoucherService() + SENTPAYMENTPROGRESS+"?id="+id;
        Map<String, Object> map = restTemplate.getForObject(url ,Map.class);
        logger.info("==== call sentPaymentProgress interface out result ：" + map);
        return map;
    }

    /**
     * paramMap请求内容请参考接口文档
     * @param paramMap
     * @return
     */
    @Override
    public Map<String, String> nullifyPayMent(List<String> paramMap,String tokenid) {
        logger.info("==== call nullifyPayMent interface into params ：" + paramMap);
        String url = fileServiceConfiguration.getPayVoucherService() + NULLIFYPAYMENT;
        Map<String,String> resultMap = new HashMap<>(1);
        HttpHeaders headers = new HttpHeaders();
        headers.add("tokenid",tokenid);
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<List<String>> requestEntity = new HttpEntity<>(paramMap, headers);
        ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
        resultMap.put("result",responseEntity.getBody());
        logger.info("==== call nullifyPayMent interface out result ：" + resultMap);
        return resultMap;
    }

    @Override
    public Map<String, Object> checkToken(String token) {
        Map<String, Object> map = restTemplate.getForObject(urlConfiguration.getSso() + CHECKTOKEN + token ,Map.class);
        return map;
    }

    @Override
    public Map<String, Object> logout(String token) {
        Map<String, Object> map = restTemplate.getForObject(urlConfiguration.getSso() + LOGOUT + token ,Map.class);
        return map;
    }

    @Override
    public List<Map<String, Object>> getAuthAgencyTree(UserDTO userDTO) {
        List<Map<String, Object>> result = null;
        // 获取有权限的单位数据
        JSONArray jsonArray = iAssetInfoService.getAuthAgency(userDTO, ApiElementConstant.AGENCY);
        // 获取所有单位数据
        List<AgencyInfo> agencyList = iAgencyInfoService.getAgencyTreeData(null,userDTO.getProvince());
        List<String> authAgencyId = null;
        if(jsonArray!=null){
            authAgencyId= jsonArray.toJavaList(String.class);
        }else{
            result = tree(agencyList, "0");
        }
        if (!StringUtils.isEmpty(authAgencyId) && authAgencyId.size() > 0) {
            // 如果是#，代表拥有全部权限
            if ("#".equals(authAgencyId.get(0))) {
                result = tree(agencyList, "0");
            } else {
                result = getAuthTree(agencyList, authAgencyId, null);
            }
        }
        List<Map<String, Object>> topTree = new ArrayList<>();
        Map<String, Object> map = new HashMap<>(1);
        map.put("label", "预算单位");
        map.put("code", "0");
        map.put("id", "0");
        map.put("children", result);
        topTree.add(map);
        return topTree;
    }

    @Override
    public List<Map<String, Object>> getAuthAgencyTrees(UserDTO userDTO,String menuid) {
        List<Map<String, Object>> result = null;
        // 获取有权限的单位数据
        JSONArray jsonArray = iAssetInfoService.getAuthAgency(userDTO, ApiElementConstant.AGENCY);
        // 获取所有单位数据
        List<AgencyInfo> agencyList = iAgencyInfoService.getAgencyTreeDatas(null,userDTO,menuid);
        List<String> authAgencyId = null;
        if(jsonArray!=null){
            authAgencyId= jsonArray.toJavaList(String.class);
        }else{
            result = tree(agencyList, "0");
        }
        if (!StringUtils.isEmpty(authAgencyId) && authAgencyId.size() > 0) {
            // 如果是#，代表拥有全部权限
            if ("#".equals(authAgencyId.get(0))) {
                result = tree(agencyList, "0");
            } else {
                result = getAuthTree(agencyList, authAgencyId, null);
            }
        }
        List<Map<String, Object>> topTree = new ArrayList<>();
        Map<String, Object> map = new HashMap<>(1);
        map.put("label", "预算单位");
        map.put("code", "0");
        map.put("id", "0");
        map.put("children", result);
        topTree.add(map);
        return topTree;
    }

    @Override
    public Map<String, Object> getFirstAuthAgencyData(UserDTO userDTO) {
        // 获取有权限的单位数据
        JSONArray jsonArray = iAssetInfoService.getAuthAgency(userDTO, ApiElementConstant.AGENCY);
        List<String> agencyList = iAgencyInfoService.getSendSalaryAgencyId(jsonArray,userDTO);
         if(agencyList.size()<1){
             return ApiResultDTO.error("单位树为空");
         }else{
             String agencyId = agencyList.get(0);
             Map<String, Object> firstAuthAgencyData = new HashMap<>();
             if(!StringUtils.isEmpty(agencyId)){
                 firstAuthAgencyData = iAgencyInfoService.getFirstAuthAgencyData(agencyId);
             }
             return firstAuthAgencyData;
         }
    }

    @Override
    public List<Map> getAgencyInfo(String tokenid, String agencyId) {
        HttpHeaders headers = new HttpHeaders();
        headers.set("tokenid", tokenid);
        headers.setContentType(MediaType.APPLICATION_JSON);
        Map<String, String> requestMap = new HashMap<>(1);
        requestMap.put("agencyguids", agencyId);
        HttpEntity<Map<String,String>> requestEntity = new HttpEntity<Map<String,String>>(null, headers);
        String url= fileServiceConfiguration.getAgencyservice() + AGENCYINFO + "?agencyguids="+agencyId;
        ResponseEntity<String> json= restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
//        String json= restTemplate.getForObject(url, String.class, headers);
        JSONObject jsonObject = JSONObject.parseObject(json.getBody());
        String rscode = jsonObject.getString("rscode");
        if (!"100000".equals(rscode)) {
            throw new AppRuntimeException("查询单位基础信息失败！");
        }
        List<Map> list = jsonObject.getJSONArray("data").toJavaList(Map.class);
        return list;
    }

    @Override
    public List<Map<String, Object>> getAgencyTree(String agencyId,UserDTO userDTO) {
        // 获取所有单位数据
        List<AgencyInfo> agencyList = iAgencyInfoService.getAgencyTreeData(agencyId,userDTO.getProvince());
        List<Map<String, Object>> result = tree(agencyList, "0");
        List<Map<String, Object>> topTree = new ArrayList<>();
        Map<String, Object> map = new HashMap<>(1);
        map.put("label", "预算单位");
        map.put("code", "0");
        map.put("id", "0");
        map.put("children", result);
        topTree.add(map);
        return topTree;
    }

    @Override
    public List<String> getAgencyChildrenId(UserDTO userDTO, String agencyId) {
        // 获取有权限的单位数据
        JSONArray jsonArray = iAssetInfoService.getAuthAgency(userDTO, ApiElementConstant.AGENCY);
        List<String> authAgencyId = null;


        // 获取所有单位数据
        List<AgencyInfo> agencyList = iAgencyInfoService.getAgencyTreeData(null,userDTO.getProvince());
        List<String> childrenList = null;
        try {
            childrenList = searchChildrenId(agencyList, agencyId);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        if(jsonArray!=null){
            authAgencyId = jsonArray.toJavaList(String.class);
        }else{
            authAgencyId=childrenList;
        }
        // 获取交集
        authAgencyId.retainAll(childrenList);
        return authAgencyId;
    }

    /**
     * 获取指定id下的叶子节点id查所有包括删除的
     * @param agencyId
     * @return
     */
    @Override
    public List<String> getAgencyChildrenIds(UserDTO userDTO, String agencyId) {
        // 获取有权限的单位数据
        JSONArray jsonArray = iAssetInfoService.getAuthAgency(userDTO, ApiElementConstant.AGENCY);
        List<String> authAgencyId = null;


        // 获取所有单位数据
        List<AgencyInfo> agencyList = iAgencyInfoService.getAgencyTree(null,userDTO.getProvince());
        List<String> childrenList = null;
        try {
            childrenList = searchChildrenId(agencyList, agencyId);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        if(jsonArray!=null){
            authAgencyId = jsonArray.toJavaList(String.class);
        }else{
            authAgencyId=childrenList;
        }
        // 获取交集
        authAgencyId.retainAll(childrenList);
        return authAgencyId;
    }

    /**
     * 获取所有单位数据树结构数据
     * @param agencyList 单位所有数据
     * @param guid 父id
     * @return
     */
    private List<Map<String, Object>> tree(List<AgencyInfo> agencyList, String guid) {
        List<Map<String, Object>> resultTree = new ArrayList<>();
        if (agencyList != null && agencyList.size() > 0) {
            for (int i = 0; i < agencyList.size() ; i++) {
                AgencyInfo agencyInfo = agencyList.get(i);
                // 顶级
                if ("1" .equals(agencyInfo.getLevelNo()) && "0".equals(guid)) {
                    List<Map<String, Object>> childrenList = null;
                    Map<String, Object> map = new HashMap<>();
                    map.put("label", agencyInfo.getAgencyCode() + "-" + agencyInfo.getAgencyName());
                    map.put("code", agencyInfo.getAgencyCode());
                    String parGuid = agencyInfo.getId();
                    map.put("id", parGuid);
                    String leaf = String.valueOf(agencyInfo.getIsLeaf());
                    map.put("isleaf", leaf);
                    if (!"1".equals(leaf)) {
                        childrenList = tree(agencyList, parGuid);
                        map.put("children", childrenList);
                    }
                    if ("1".equals(leaf)) {
                        resultTree.add(map);
                    } else if (!StringUtils.isEmpty(childrenList) && childrenList.size() > 0) {
                        resultTree.add(map);
                    }
                } else  {
                    String superguid = agencyInfo.getParentId();
                    if (guid.equals(superguid)) {
                        List<Map<String, Object>> childrenList = null;
                        Map<String, Object> map = new HashMap<>();
                        map.put("label", agencyInfo.getAgencyCode() + "-" + agencyInfo.getAgencyName());
                        map.put("code", agencyInfo.getAgencyCode());
                        String parGuid = agencyInfo.getId();
                        map.put("id", parGuid);
                        String leaf = String.valueOf(agencyInfo.getIsLeaf());
                        map.put("isleaf", leaf);
                        if (!"1".equals(leaf)) {
                            childrenList = tree(agencyList, parGuid);
                            map.put("children", childrenList);
                        }
                        if ("1".equals(leaf)) {
                            resultTree.add(map);
                        } else if (!StringUtils.isEmpty(childrenList) && childrenList.size() > 0) {
                            resultTree.add(map);
                        }
                    }
                }
            }
        }
        return resultTree;
    }

    /**
     * 获取权限单位最顶级的节点id，并根据id获取下级树
     * @param agencyList 单位所有数据
     * @param authAgencyIdList  有权限的单位id
     * @param agencyId 上级id 默认 null
     * @return
     */
    private List<Map<String, Object>> getAuthTree(List<AgencyInfo> agencyList, List<String> authAgencyIdList, String agencyId) {
        List<Map<String, Object>> resultTree = new ArrayList<>();
        List<String> topResultList = new ArrayList<>();
        // 如果单位id是空，获取权限单位id的顶级节点id
        if (StringUtils.isEmpty(agencyId)) {
            // 循环权限单位id集合，找最顶级的id
            for (AgencyInfo agencyInfo: agencyList) {
                for (int i = 0; i< authAgencyIdList.size(); i++) {
                    String authAgencyId = authAgencyIdList.get(i);

                    // 如果权限单位id和当前数据id相等
                    if (authAgencyId.equals(agencyInfo.getId())) {
                        String parentId = agencyInfo.getParentId();
                        // 如果本身不是父节点
                        if (!"0".equals(parentId)) {
                            // 获取最顶级数据id
                            List<Map<String, Object>> topIds = getAuthTree(agencyList, authAgencyIdList, parentId);
                            if (topIds.size() > 0) {
                                String topId = topIds.get(0).get("topId").toString();
                                // 如果数组中不包含当前顶级id ，则将最顶级id添加到数组中，如果包含直接返回
                                if (!StringUtils.isEmpty(topResultList) && topResultList.size() > 0) {
                                    if (!topResultList.contains(topId)) {
                                        topResultList.add(topId);
                                    } else {
                                        break;
                                    }
                                } else {
                                    topResultList.add(topId);
                                }
                                // 根据最顶级单位id获取下级有权限的树结构数据
                                List<Map<String, Object>> treeData = authTree(agencyList, authAgencyIdList, topId, topId);
                                resultTree.addAll(treeData);
                            }
                            break;
                        }
                    }
                }
            }
        } else {
            for (AgencyInfo agencyInfo: agencyList) {
                // 如果当前id和传进来的id相等
                if (agencyId.equals(agencyInfo.getId())) {
                    String parentId = agencyInfo.getParentId();
                    // 如果本身不是父节点
                    if (!"0".equals(parentId)) {
                        List<Map<String, Object>> topIds = getAuthTree(agencyList, authAgencyIdList, parentId);
                        resultTree.addAll(topIds);
                        break;
                    } else {
                        // 如果本身就是父节点，直接返回
                        Map<String, Object> map = new HashMap<>(1);
                        map.put("topId", agencyId);
                        resultTree.add(map);
                        break;
                    }
                }
            }
        }
        return resultTree;
    }

    /**
     * 根据最顶级id获取下级有权限的单位树
     * @param agencyList  所有单位集合
     * @param authAgencyIdList  有权限的单位id
     * @param guid  父id
     * @param topId  最顶级id
     * @return
     */
    private List<Map<String, Object>> authTree(List<AgencyInfo> agencyList, List<String> authAgencyIdList, String guid, String topId) {
        // 最终数据集合
        List<Map<String, Object>> resultTree = new ArrayList<>();
        if (agencyList != null && agencyList.size() > 0) {
            for (int i = 0; i < agencyList.size() ; i++) {
                AgencyInfo agencyInfo = agencyList.get(i);
                String id = agencyInfo.getId();
                String parentId = agencyInfo.getParentId();
                // 如果最顶级id不是空，并且获取到的数据和最顶级id相等
                if (!StringUtils.isEmpty(topId) && id.equals(topId) && "0".equals(parentId)) {
                    Map<String, Object> map = new HashMap<>(4);
                    map.put("label", agencyInfo.getAgencyCode() + "-" + agencyInfo.getAgencyName());
                    map.put("code", agencyInfo.getAgencyCode());
                    String parGuid = agencyInfo.getId();
                    map.put("id", parGuid);
                    String leaf = String.valueOf(agencyInfo.getIsLeaf());
                    map.put("isleaf", leaf);
                    // 如果是叶子节点，获取下级单位树数据
                    if (!"1".equals(leaf)) {
                        List<Map<String, Object>> childrenList = authTree(agencyList, authAgencyIdList, parGuid, null);
                        map.put("children", childrenList);
                    }
                    resultTree.add(map);
                    break;
                }
                // 获取下级有权限的数据
                else  {
                    String superguid = agencyInfo.getParentId();
                    // 如果当前数据的父id和传进来的一致
                    if (guid.equals(superguid)) {
                        String leaf = String.valueOf(agencyInfo.getIsLeaf());
                        String parGuid = agencyInfo.getId();
                        // 如果是叶子节点，获取下级单位树数据
                        if (!"1".equals(leaf)) {
                            Map<String, Object> map = new HashMap<>(4);
                            map.put("label", agencyInfo.getAgencyCode() + "-" + agencyInfo.getAgencyName());
                            map.put("code", agencyInfo.getAgencyCode());
                            map.put("id", parGuid);
                            map.put("isleaf", leaf);
                            List<Map<String, Object>> childrenList = authTree(agencyList, authAgencyIdList, parGuid, null);
                            map.put("children", childrenList);
                            // 如果获取到的子集有数据则添加到最终集合中
                            if (!StringUtils.isEmpty(childrenList) && childrenList.size() > 0) {
                                resultTree.add(map);
                            }
                        } else {
                            // 如果不是叶子节点，判断是否在权限内，如果在，则添加到结果中
                            if (authAgencyIdList.contains(parGuid)) {
//                                authAgencyIdList.remove(parGuid);
                                Map<String, Object> map = new HashMap<>(4);
                                map.put("label", agencyInfo.getAgencyCode() + "-" + agencyInfo.getAgencyName());
                                map.put("code", agencyInfo.getAgencyCode());
                                map.put("id", parGuid);
                                map.put("isleaf", leaf);
                                resultTree.add(map);
                            }
                            continue;
                        }
                    }
                }
            }
        }
        return resultTree;
    }

    /**
     * 递归查询下级叶子节点的单位id
     * @param infoList  所有单位id集合
     * @param agencyId  单位id
     * @return
     */
    private List<String> searchChildrenId(List<AgencyInfo> infoList, String agencyId) throws IOException, ClassNotFoundException {
        List<String> childrenIds = new ArrayList<>();
        if (infoList != null && infoList.size() > 0) {
            for (int i = 0; i < infoList.size() ; i++) {
                AgencyInfo agencyInfo = infoList.get(i);
                // id相等，并且是叶子节点
                if (agencyId.equals(agencyInfo.getId()) && agencyInfo.getIsLeaf() == 1) {
                    childrenIds.add(agencyInfo.getId());
                } else if (agencyId.equals(agencyInfo.getParentId())) {
                    // 叶子节点
                    if (agencyInfo.getIsLeaf() == 1) {
                        childrenIds.add(agencyInfo.getId());
                    } else {  // 非叶子节点，还有下级
//                        List<AgencyInfo> childrenInfos = infoList;
                        // 拷贝list
//                        List<AgencyInfo> childrenInfos = CommonUtils.deepCopy(infoList);
                        List<AgencyInfo> childrenInfos = infoList.stream().collect(Collectors.toList());
//                        Collections.copy(childrenInfos, infoList);
//                        List<AgencyInfo> childrenInfos = new ArrayList(list);
                        childrenInfos.remove(agencyInfo);
                        childrenIds.addAll(searchChildrenId(childrenInfos, agencyInfo.getId()));
                    }
                }
                // id相等，并且是非叶子节点
                else if (agencyId.equals(agencyInfo.getId()) && agencyInfo.getIsLeaf() == 0) {
                    List<AgencyInfo> childrenInfos = infoList;
                    childrenInfos.remove(agencyInfo);
                    childrenIds.addAll(searchChildrenId(childrenInfos, agencyInfo.getId()));
                }
            }
        }
        return childrenIds;
    }

//    @Override
//    public List<PersonOperate> getPersonInfoByAgency4Buget(String agency_id, String code) throws FileNotFoundException {
//        List<PersonOperate>  resultList = new ArrayList<>();
//        if ("excel".equals(code)) {
//            resultList = getExcelPersonInfo();
//        } else if ("api".equals(code)) {
//            resultList = getApiPersonInfo(agency_id);
//        }
//        return resultList;
//    }

//    private List<PersonOperate> getExcelPersonInfo() throws FileNotFoundException {
//        String path = "C:\\Users\\89860\\Desktop\\工资项目\\长春市数据\\导入数据\\import-personInfo.xlsx";
//        File file = new File(path);
//        InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
//        ExcelResult<PersonInfoBaseDataModel> personAll = excelParsingService.readExcelWithModel(inputStream, PersonInfoBaseDataModel.class, ExcelTypeEnum.valueOf(inputStream));
//        List<PersonInfoBaseDataModel> successList = personAll.getSuccessList();
//        System.out.println(successList);
//        JSONArray jsonArray = JSON.parseArray(JSONObject.toJSONString(successList));
//        List<PersonOperate> list = getPersonInfoByAgency4BugetData(jsonArray);
//        return list;
//    }

    private List<PersonOperate> getApiPersonInfo(String agency_id) {
        String url="http://10.207.100.8:8084/v1/persons/getAgencyPersonInfo?agencyguids="+agency_id;
        JSONArray jsonArray = null;
        HttpHeaders headers = new HttpHeaders();
        headers.add("tokenid","97ddf29aa1d9942b4e05e01a24deebea");
        HttpEntity< String > requestEntity = new HttpEntity<>(null, headers);
        ResponseEntity<JSONObject> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, JSONObject.class);

        JSONObject jsonObject = responseEntity.getBody();
        if(!SysUtils.isNullOrEmpty(jsonObject) && "100000".equals(jsonObject.getString("rscode"))) {
            jsonArray = jsonObject.getJSONObject("data").getJSONArray(agency_id);
        }
        List<PersonOperate> list = getPersonInfoByAgency4BugetData(jsonArray);
        return list;
    }


    private List<PersonOperate> getPersonInfoByAgency4BugetData(JSONArray jsonArray) {
        List<PersonOperate>  resultList=new ArrayList<>();
        if(jsonArray != null) {
            for (int i = 0; i < jsonArray.size(); i++) {
                PersonOperate p = new PersonOperate();//创建人员类
                JSONObject obj = jsonArray.getJSONObject(i);
                String id = SysUtils.generateGuid();
                /**
                 主键
                 */
                p.setId(SysUtils.generateGuid());//逐个赋值
                /**
                 创建时间
                 */
                p.setCreateTime(String.valueOf(DateUtils.getCurrentTimeStamp()));
                /**
                 修改时间
                 */
                p.setUpdateTime(String.valueOf(DateUtils.getCurrentTimeStamp()));
                /**
                 姓名
                 */
                p.setPersonName(obj.getString("per_name"));
                /**
                 性别
                 */
                p.setSexCode(obj.getString("sex_code"));
                /**
                 证件类型
                 */
                p.setIdenTypeCode("01");
                /**
                 证件号码
                 */
                p.setIdenNo(obj.getString("iden_no"));
                /**
                 * 出生日期
                 */
                p.setBirthday(obj.getString("borndate"));
                /**
                 国籍
                 */
                p.setNation(obj.getString("nation"));
                /**
                 民族代码
                 */
                p.setNatCode(obj.getString("nat_code"));
                /**
                 人员状态
                 */
                p.setState(obj.getString("state"));
                /**

                 /**
                 参加工作时间
                 */
                p.setWorkInitDate(obj.getString("work_init_date"));
                /**
                 号核实标识
                 */
                p.setIdenIsVerify(SystemDictConstant.NO_SUBMIT);

                /**
                 删除标识
                 */
                p.setIsDeleted(SystemDictConstant.IS_FALSE);

                /**
                 * 以下为拓展信息
                 */

                /**
                 * 人员id
                 */
                p.setPersonId(id);

                /**
                 * 机构id
                 */
                p.setAgencyId(obj.getString("agency_id"));

                /**
                 * 组织机构
                 */
                p.setAgencyCode(obj.getString("agency_code"));
                /**
                 * 入职时间
                 */
                p.setEnterAgencyDate(obj.getString("enter_agency_date"));

                /**
                 * 人员类别
                 */
                p.setPersonTypeCode(obj.getString("per_sta_code"));
                /**
                 * 人员身份
                 */
                p.setPersonIdeCode(SystemDictConstant.IS_SUBMIT);
                /**
                 * 工资卡银行
                 */
                p.setSalaCardBank(obj.getString("sala_card_bank"));

                /**
                 * 工资卡号
                 */
                p.setSalaCardNo(obj.getString("sala_card_no"));
                /**
                 * 工资类别
                 */
                p.setMeritPayCode(obj.getString("merit_pay_code"));

                /**
                 * 生效时间
                 */
                p.setStartDate("2020-01-01");
                /**
                 * 工资类别
                 */
                p.setMeritPayCode(obj.getString("sala_gr"));
                /**
                 * 学历
                 */
                p.setSchRecCode(obj.getString("sch_rec_code"));
                /**
                 * 职务
                 */
                p.setPosCode(obj.getString("pos_code"));
                /**
                 * 职级
                 */
                p.setGrCode(obj.getString("gr_code"));
                /**
                 * 技术等级
                 */
                p.setTecGrCode(obj.getString("cc496"));
                /**
                 * 是否在编
                 */
                p.setIsAuth(SystemDictConstant.IS_TRUE);
                /**
                 * 工资级别
                 */
                p.setSalaGrCode(obj.getString("cc494"));
                /**
                 * 当前人员状态
                 */
                p.setPersonState(obj.getString("per_sta_code"));

                /**
                 * 人员来源
                 */
                p.setPerSourceCode(obj.getString("personnelsource"));
                /**
                 * 是否特殊岗位
                 */
                p.setIsSpecialPost(SystemDictConstant.IS_FALSE);

                /**
                 * 是否统发
                 */
                p.setIsUniSala(SystemDictConstant.IS_TRUE);

                p.setOperateCode("add");
                p.setVerifyState(SystemDictConstant.IS_AUDIT);
                p.setIsReal(SystemDictConstant.IS_FALSE);
                if ("0".equals(obj.getString("is_deleted")) && "1".equals(obj.getString("is_uni_sala"))) {
                    resultList.add(p);
                }
            }
        }
        return resultList;
    }

    /**
     * 获取菜单id
     * @param wfActionDTO
     * @return
     */
    @Override
    public String getMenuid(WfActionDTO wfActionDTO) {
        logger.info(" 获取工作流节点信息 ： " + wfActionDTO.toString());
        String menuid = "";
        String url = urlConfiguration.getBpmnx() + String.format(WORKFLOW_INTODO, wfActionDTO.getProcessDefKey(),
                wfActionDTO.getBusinessKeys(), wfActionDTO.getProvince(), wfActionDTO.getYear());
        String str = restTemplate.getForObject(url, String.class);
        JSONObject jsonObject = JSON.parseObject(str);
        if ("100000".equals(jsonObject.get("rscode"))) {
            JSONArray jsonArray = jsonObject.getJSONArray("data");
            menuid =  jsonArray.getJSONObject(0).getString("menuGuid");
        } else {
            throw new AppRuntimeException((String) jsonObject.get("result"));
        }
        return menuid;
    }

    /**
     * 平台推送数据(Async异步方法)
     */
    @Async
    @Override
    public void pushMessageToApaas(UserDTO userDTO,String agengcyId,String message) {
        String url = urlConfiguration.getPermservice()+SYSNOTICES;

        MultiValueMap<String, String> resultMap = new LinkedMultiValueMap<>();
        resultMap.add("notices","[{\"content\":\""+message+"\",\"noticetype\":\"2\",\"rectype\":\"2\",\"actiontype\":\"0\"}]");
        resultMap.add("agencyids","[\""+agengcyId+"\"]");
        resultMap.add("appguid","salary");
        resultMap.add("year",userDTO.getYear()+"");
        resultMap.add("province",userDTO.getProvince());


        String str = restTemplate.postForObject(url, resultMap, String.class);
        logger.info(" 返回信息 ： " + str);
        //resultMap.put("result",responseEntity.getBody());
    }

    /**
     * 冻结指标
     * @param sum_id
     * @param amount
     * @param province
     * @param year
     * @param specialSql
     * @return
     */
    @Async
    @Override
    public Map<String, String> gocpurbudgetFrozen(String sum_id, String amount, String province, String year, String specialSql) {
        String url = fileServiceConfiguration.getBudgetService()+GOCPURBUDGETFROZEN;
        Map<String, Object> requestMap = new HashMap<>(4);
        requestMap.put("sum_id", sum_id);
        requestMap.put("amount", amount);
        requestMap.put("year", year);
        requestMap.put("province", province);
        String json = restTemplate.getForObject(url+"?sum_id={sum_id}&amount={amount}&year={year}&province={province}",
                String.class, requestMap);
        Map<String,String> resultMap = new HashMap<>();
        JSONObject jsonObject = JSON.parseObject(json);
        if(!SysUtils.isNullOrEmpty(jsonObject) && "100000".equals(jsonObject.getString("rscode"))){
            resultMap.put("rscode","100000");
        }
        return resultMap;
    }

    /**
     * 指标解冻
     * @param sum_id
     * @param amount
     * @param province
     * @param year
     * @param specialSql
     * @return
     */
    @Async
    @Override
    public Map<String, String> gocpurbudgetThaw(String sum_id, String amount, String province, String year, String specialSql) {
        String url = fileServiceConfiguration.getBudgetService()+GOCPURBUDGETTHAW;
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("sum_id", sum_id);
        requestMap.put("amount", amount);
        requestMap.put("year", year);
        requestMap.put("province", province);
        String json = restTemplate.getForObject(url+"?sum_id={sum_id}&amount={amount}&year={year}&province={province}",
                String.class, requestMap);
        Map<String,String> resultMap = new HashMap<>();
        JSONObject jsonObject = JSON.parseObject(json);
        if(!SysUtils.isNullOrEmpty(jsonObject) && "100000".equals(jsonObject.getString("rscode"))){
            resultMap.put("rscode","100000");
        }
        return resultMap;
    }

    @Override
//    @GlobalTransactional(timeoutMills=300000)//@Transactional(rollbackFor = Exception.class)
    public Map<String, String> batchGocpurbudgetFrozen(List<Map<String,Object>> payList, String province, String year, String specialSql) throws Exception {
        //批量冻结指标
        List<Map<String,Object>> mapList =new ArrayList<>();
        //冻结合单
        Map<String,Object> sumIdKeyMap=new HashMap<>();
        List<Map<String,Object>> zeropayList=new ArrayList<>();//0额度信息
        for(Map<String,Object> rapm:payList){
            if(new BigDecimal(rapm.get("amt").toString()).compareTo(new BigDecimal("0.00"))==0){
                zeropayList.add(rapm);
                continue;
            }
            //若合单内不存在则直接插入
            if(StringUtils.isEmpty(sumIdKeyMap.get(rapm.get("bgt_id").toString()))) {
                sumIdKeyMap.put(rapm.get("bgt_id").toString(), new BigDecimal(rapm.get("amt").toString()));
            }else{//若存在则相加后再进行插入
                BigDecimal awonser=new BigDecimal(sumIdKeyMap.get(rapm.get("bgt_id")).toString()).add(new BigDecimal(rapm.get("amt").toString()));
                sumIdKeyMap.put(rapm.get("bgt_id").toString(), awonser);
            }
        }
        if(!CollectionUtils.isEmpty(zeropayList)){
            payList.removeAll(zeropayList);//将0额度排除掉
        }
        for(String key:sumIdKeyMap.keySet()){
            Map<String,Object> map=new HashMap<>();
            map.put("sum_id",key);
            map.put("amount",sumIdKeyMap.get(key));
            mapList.add(map);
        }

        String url = fileServiceConfiguration.getBudgetService()+BATCHGOCPURBUDGETFROZEN;
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("reData",mapList);
        requestMap.put("year", year);
        requestMap.put("province", province);
        requestMap.put("specialSql", "");
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity< Map<String, Object> > requestEntity = new HttpEntity<>(requestMap, headers);
        ResponseEntity<JSONObject> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, JSONObject.class);

        String json = responseEntity.getBody().toJSONString();
        //restTemplate.postForObject(url, JSON.toJSON(requestMap), String.class);
        Map<String, String>  resultMap=new HashMap<>();
        JSONObject jsonObject = JSON.parseObject(json);
        if(!SysUtils.isNullOrEmpty(jsonObject) && "100000".equals(jsonObject.getString("rscode"))){
            resultMap.put("rscode","100000");
            //保存已锁定指标
            iPayMentLockDao.batchSavePayMentLock(payList,province);
        }else {
            logger.info("指标冻结失败:"+jsonObject.getString("msg"));
            throw new AppRuntimeException("指标冻结失败:"+jsonObject.getString("msg"));
        }
        return resultMap;
    }
    @Override
    @GlobalTransactional(timeoutMills=300000)//@Transactional(rollbackFor = Exception.class)
    public Map<String, String> batchGocpurbudgetThaw(List<Map<String,Object>> payList, String province, String year, String specialSql) {
        logger.info("====指标解冻开始=====");
        List<Map<String,Object>> mapList =new ArrayList<>();
        List<String> bgtids=new ArrayList<>();
        Map<String,Object> sumIdKeyMap=new HashMap<>();
        for(Map<String,Object> rapm:payList){
            if(StringUtils.isEmpty(sumIdKeyMap.get(rapm.get("bgt_id").toString()))) {
                sumIdKeyMap.put(rapm.get("bgt_id").toString(), new BigDecimal(rapm.get("amt").toString()));
            }else{
                BigDecimal awonser=new BigDecimal(sumIdKeyMap.get(rapm.get("bgt_id")).toString()).add(new BigDecimal(rapm.get("amt").toString()));
                sumIdKeyMap.put(rapm.get("bgt_id").toString(), awonser);
            }
        }
        for(String key:sumIdKeyMap.keySet()){
            Map<String,Object> map=new HashMap<>();
            map.put("sum_id",key);
            map.put("amount",sumIdKeyMap.get(key));
            mapList.add(map);
            bgtids.add(key);
        }
        logger.info("====解冻指标====="+bgtids.toString());
        String url = fileServiceConfiguration.getBudgetService()+BATCHGOCPURBUDGETTHAW;
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("reData",mapList);
        requestMap.put("year", year);
        requestMap.put("province", province);
        requestMap.put("specialSql", "");
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity< Map<String, Object> > requestEntity = new HttpEntity<>(requestMap, headers);
        ResponseEntity<JSONObject> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, JSONObject.class);
        String json = responseEntity.getBody().toJSONString();
        Map<String, String>  resultMap=new HashMap<>();
        JSONObject jsonObject = JSON.parseObject(json);
        if(!SysUtils.isNullOrEmpty(jsonObject) && "100000".equals(jsonObject.getString("rscode"))){
            resultMap.put("rscode","100000");
            //解锁指标
            iPayMentLockDao.batchUpdatePayMentLockByBgtId(bgtids);
            logger.info("====解冻指标完成=====");
        }else{
            logger.info("指标解冻失败:"+jsonObject.getString("msg"));
            throw new AppRuntimeException("指标解冻失败:"+jsonObject.getString("msg"));
        }

        return resultMap;
    }

    @Override
    public List<Map<String, Object>> queryBaseDataList(Map<String, Object> queryParam) {
        return iBaseDateDao.queryBaseDataList(queryParam);
    }
    @Override
    public Map<String, Object> queryBaseDataMap(String type,String mofDivCode) {
        Map<String,Object> queryParam=new HashMap<>();
        queryParam.put("type",type);
        queryParam.put("mof_div_code",mofDivCode);
        List<Map<String, Object>> baseDataList= iBaseDateDao.queryBaseDataList(queryParam);
        Map<String, Object> meritMap=new HashMap<>();
        for(Map map:baseDataList){
            meritMap.put(map.get("code").toString(),map.get("name"));
        }

        return meritMap;
    }

    @Override
    public Map<String, Object> querySalaryBaseDataMap(String mofDivCode) {

        List<SalaryBasedata> baseDataList= salaryBasedataDao.selectAllSalary(mofDivCode);
        Map<String, Object> meritMap=new HashMap<>();
        for(SalaryBasedata sb:baseDataList){
            meritMap.put(sb.getId(),sb.getSalaryName());
        }

        return meritMap;
    }

    @Override
    public ConfigCtrl selectConfigCtrlByTypeMof(String type, String mof_div_code) {
        return iConfigCtrlDao.selectConfigCtrlByTypeMof(type,mof_div_code);
    }
    /**
     * 获取平台单位单位树
     * @param userDTO
     * @return
     */
    @Override
    public List<Map<String, Object>> getAgency(UserDTO userDTO) {
        List<Map<String, Object>> result = null;
        // 获取有权限的单位数据
        JSONArray jsonArray = iAssetInfoService.getBaseDataTree(ApiElementConstant.AGENCY,userDTO.getProvince());
        // 获取所有单位数据 并抢转成listmap
        List<Map<String, Object>> mapList = (List<Map<String,Object>>) jsonArray.parse(String.valueOf(jsonArray));
        //查询 info表中的的所有id
        List<AgencyInfo> agencyInfoList=agencyInfoDao.queryid(userDTO.getProvince());
        List<AgencyInfo> agencyList = new ArrayList<>();
        //将map 循环并存入AgencyInfo对象中 然后存入agencyInfoList里
        for(Map<String,Object> map:mapList){
            if(SysUtils.isNullOrEmpty(map.get("code"))||SysUtils.isNullOrEmpty(map.get("levelno"))||SysUtils.isNullOrEmpty(map.get("isleaf"))||SysUtils.isNullOrEmpty(map.get("name"))||SysUtils.isNullOrEmpty(map.get("superguid"))||SysUtils.isNullOrEmpty(map.get("bizkey"))){
                continue;
            }
            AgencyInfo agencyInfo=new AgencyInfo();
            agencyInfo.setLevelNo(map.get("levelno").toString());
            agencyInfo.setAgencyName(map.get("name").toString());
            agencyInfo.setAgencyCode(map.get("code").toString());
            agencyInfo.setId(map.get("bizkey").toString());
            agencyInfo.setIsLeaf((Integer) map.get("isleaf"));
            agencyInfo.setParentId(map.get("superguid").toString());
            //在前台状态做一个标记
            for (int i = 0; i < agencyInfoList.size(); i++) {
                //判断表中的id 和平台获取的id 是否相等 如果相等 set一个标记0已设置1为设置
                if (agencyInfo.getId().equals(agencyInfoList.get(i).getId())) {
                    agencyInfo.setYesNo(0);
                    break;
                }else {
                    agencyInfo.setYesNo(1);
                }
            }
            agencyList.add(agencyInfo);
        }
        //将 数据 去trees 中做树结构
        result = trees(agencyList, "0");
        List<Map<String, Object>> topTree = new ArrayList<>();
        Map<String, Object> map = new HashMap<>(1);
        map.put("label", "预算单位");
        map.put("code", "0");
        map.put("id", "0");
        map.put("parentId", "0");
        map.put("levelNo"," ");
        map.put("yesNo","");
        map.put("children", result);
        topTree.add(map);
        return topTree;
    }



    /**
     *
     * 获取所有单位数据树结构数据
     * @param agencyList 单位所有数据
     * @param guid 父id
     * @return
     */
    private List<Map<String, Object>> trees(List<AgencyInfo> agencyList, String guid) {
        List<Map<String, Object>> resultTree = new ArrayList<>();
        if (agencyList != null && agencyList.size() > 0) {
            for (int i = 0; i < agencyList.size() ; i++) {
                AgencyInfo agencyInfo = agencyList.get(i);
                // 顶级
                if ("1" .equals(agencyInfo.getLevelNo()) && "0".equals(guid)) {
                    List<Map<String, Object>> childrenList = null;
                    Map<String, Object> map = new HashMap<>();
                    map.put("label",  agencyInfo.getAgencyName());
                    map.put("code", agencyInfo.getAgencyCode());
                    String parGuid = agencyInfo.getId();
                    map.put("id", parGuid);
                    map.put("parentId", agencyInfo.getParentId());
                    map.put("levelNo",agencyInfo.getLevelNo());
                    map.put("yesNo",agencyInfo.getYesNo());
                    String leaf = String.valueOf(agencyInfo.getIsLeaf());
                    map.put("isleaf", leaf);
                    if (!"1".equals(leaf)) {
                        childrenList = trees(agencyList, parGuid);
                        map.put("children", childrenList);
                    }
                    if ("1".equals(leaf)) {
                        resultTree.add(map);
                    } else if (!StringUtils.isEmpty(childrenList) && childrenList.size() > 0) {
                        resultTree.add(map);
                    }
                } else  {
                    String superguid = agencyInfo.getParentId();
                    if (guid.equals(superguid)) {
                        List<Map<String, Object>> childrenList = null;
                        Map<String, Object> map = new HashMap<>();
                        map.put("label", agencyInfo.getAgencyName());
                        map.put("code", agencyInfo.getAgencyCode());
                        String parGuid = agencyInfo.getId();
                        map.put("id", parGuid);
                        map.put("parentId", agencyInfo.getParentId());
                        map.put("levelNo",agencyInfo.getLevelNo());
                        map.put("yesNo",agencyInfo.getYesNo());
                        String leaf = String.valueOf(agencyInfo.getIsLeaf());
                        map.put("isleaf", leaf);
                        if (!"1".equals(leaf)) {
                            childrenList = trees(agencyList, parGuid);
                            map.put("children", childrenList);
                        }
                        if ("1".equals(leaf)) {
                            resultTree.add(map);
                        } else if (!StringUtils.isEmpty(childrenList) && childrenList.size() > 0) {
                            resultTree.add(map);
                        }
                    }
                }
            }
        }
        return resultTree;
    }

    @Override
    public List<Map<String, Object>> getNotAuditAuthAgencyTree(UserDTO userDTO,String menuid) {
        List<Map<String, Object>> result = null;
        // 获取有权限的单位数据
        JSONArray jsonArray = iAssetInfoService.getAuthAgency(userDTO, ApiElementConstant.AGENCY);
        // 获取所有单位数据
        List<AgencyInfo> agencyList = iAgencyInfoService.getNotAuditAuthAgencyTreeData(null,userDTO,menuid);
        List<String> authAgencyId = null;
        if(jsonArray!=null){
            authAgencyId= jsonArray.toJavaList(String.class);
        }else{
            result = tree(agencyList, "0");
        }
        if (!StringUtils.isEmpty(authAgencyId) && authAgencyId.size() > 0) {
            // 如果是#，代表拥有全部权限
            if ("#".equals(authAgencyId.get(0))) {
                result = tree(agencyList, "0");
            } else {
                result = getAuthTree(agencyList, authAgencyId, null);
            }
        }
        List<Map<String, Object>> topTree = new ArrayList<>();
        Map<String, Object> map = new HashMap<>(1);
        map.put("label", "预算单位");
        map.put("code", "0");
        map.put("id", "0");
        map.put("children", result);
        topTree.add(map);
        return topTree;
    }
    /**
     * 获取工作流查询语句  sql中调用
     * @param wfActionDTO
     * @return
     */
    @Override
    public String getWorkflowWheresql(WfActionDTO wfActionDTO,String alias,String ...processDefKey) {
        if(processDefKey.length==0) {
            wfActionDTO.setProcessDefKey("salary_agency_verify");
        }else{
            wfActionDTO.setProcessDefKey(processDefKey[0]);
        }
        logger.info(" 获取工作流节点信息 ： " + wfActionDTO.toString());
        String menuid = "";
        String url = urlConfiguration.getBpmnx() + WORKFLOW_WHERESQL;
        String json = restTemplate.getForObject(
                url
                        + "?processDefKey={processDefKey}&menuguid={menuguid}&province={province}&year={year}&statuses"
                        + "={status}&bizKeyName={bizKeyName}&alias={alias}&whereSqlType={whereSqlType}",
                String.class, new Object[] { wfActionDTO.getProcessDefKey(), wfActionDTO.getMenuguid(), wfActionDTO.getProvince(),wfActionDTO.getYear(),
                        wfActionDTO.getStatus(), wfActionDTO.getBizKeyName() ,alias,"1"});// whereSqlType、 1:则返回IN SQL  2或不传 :默认返回EXISTS SQL

        JSONObject jsonObject = JSON.parseObject(json);
        if(!SysUtils.isNullOrEmpty(jsonObject) && "100000".equals(jsonObject.getString("rscode"))){
            JSONArray jsonArray = jsonObject.getJSONArray("data");
            return jsonArray.getJSONObject(0).getString("wheresql");
        }
        return "";
    }
    /**
     * 获取工作流查询语句  sql中调用
     * @param paramKey
     * @param province
     * @param year
     * @return
     */
    @Override
    public String getParamsConfig(String paramKey,String appKey,String province,String year) throws Exception {

        String url = urlConfiguration.getConfigureservice() + PARAMS_CONFIG;
        String json = restTemplate.getForObject(
                url+"/{paramKey}/{appKey}/{province}/{year}",
                String.class, new Object[] { paramKey,appKey,province,year});

        JSONObject jsonObject = JSON.parseObject(json);
        if(!SysUtils.isNullOrEmpty(jsonObject) && "100000".equals(jsonObject.getString("rscode"))){
            JSONArray jsonArray = jsonObject.getJSONArray("data");
            if(SysUtils.isNullOrEmpty(jsonArray)){
                throw new AppRuntimeException("未找到退回工资节点菜单！请查看系统参数配置");
            }
            return jsonArray.getJSONObject(0).getString("value");
        }
        return "";
    }

}
